#include "slepfiletable.h"
#include "slepfileoperations.h"
#include "sleprandomdata.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QFileDialog>
#include "viewer.h"

SLEPFileTable::SLEPFileTable(QWidget *parent):QWidget(parent){
    slepItemList = new QList<SLEPItem>;
    itemModel = new QStandardItemModel(0,4,this);
    itemModel->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"),Qt::EditRole);
    itemModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Type"),Qt::DisplayRole);
    itemModel->setHeaderData(2, Qt::Horizontal, QObject::tr("Info"), Qt::EditRole );
    itemModel->setHeaderData(3, Qt::Horizontal, QObject::tr("Full filename"),Qt::DisplayRole);

    treeView = new QTreeView;
    treeView->setRootIsDecorated(false);
    treeView->setAlternatingRowColors(true);
    treeView->setModel(itemModel);
    treeView->setSortingEnabled(true);
    treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
    treeView->setSelectionMode(QAbstractItemView::SingleSelection);

    selection = new QItemSelectionModel(itemModel);
    treeView->setSelectionModel(selection);

    buttonAddMatrix = new QPushButton(tr("Add Matrix"),this);
    buttonAddVector = new QPushButton(tr("Add Vector"),this);
    buttonRemove = new QPushButton(tr("Remove"),this);
    buttonAddRandomData = new QPushButton(tr("New Random Data"),this);
    buttonView = new QPushButton(tr("View"),this);

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(treeView,0,0,1,5);
    mainLayout->addWidget(buttonAddMatrix,1,0,1,1);
    mainLayout->addWidget(buttonAddVector,1,1,1,1);
    mainLayout->addWidget(buttonRemove,1,2,1,1);
    mainLayout->addWidget(buttonAddRandomData,1,3,1,1);
    mainLayout->addWidget(buttonView,1,4,1,1);
    setLayout(mainLayout);
    connect(buttonAddMatrix, SIGNAL(clicked()),this, SLOT(actAddMatrix()));
    connect(buttonAddVector, SIGNAL(clicked()), this, SLOT(actAddVector()));
    connect(buttonRemove, SIGNAL(clicked()), this, SLOT(actRemove()));
    connect(buttonAddRandomData, SIGNAL(clicked()), this, SLOT(actAddRandomData()));
    connect(buttonView, SIGNAL(clicked()), this, SLOT(actView()));
}

SLEPFileTable::~SLEPFileTable(){
}


QStandardItemModel* SLEPFileTable::getItemModel(){
    return itemModel;
}

QList<SLEPItem>* SLEPFileTable::getSlepItemList(){
    return slepItemList;
}

void SLEPFileTable::setModel(QStandardItemModel* model,QList<SLEPItem>* list){
    itemModel = model;
    slepItemList = list;
    treeView->setModel(itemModel);
    selection = new QItemSelectionModel(itemModel);
    treeView->setSelectionModel(selection);
}

void SLEPFileTable::actAddMatrix(){
    int i;
    SLEPItem item;
    QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open matrix file"), tr("."), tr("All Formats (*.mat *.matb *.mtx *.mtb *.ijv *.ccs *.csc *.crs *.csr);;"
                                                                                                    "Matrix (*.mat);;"
                                                                                              "Matrix (binary storage) (*.matb *.mtx *.mtb);;"
                                                                                              "Sparse IJV Format (*.ijv);;"
                                                                                              "Sparse - Compressed Column Storage(*.ccs *.csc);;"
                                                                                              "Sparse - Compressed Row Storage(*.crs *.csr);;"
                                                                                              "All Files(*.*)"));


    for(i=0; i<fileNames.size(); i++){
        if( (QFileInfo(fileNames.at(i)).suffix().compare("mtx",Qt::CaseInsensitive)==0)
                    || (QFileInfo(fileNames.at(i)).suffix().compare("mtb",Qt::CaseInsensitive)==0)
                    || (QFileInfo(fileNames.at(i)).suffix().compare("matb",Qt::CaseInsensitive)==0) )
            item = SLEPFileOperations::readFile(fileNames.at(i));
        else
            item = SLEPFileOperations::readTextFile(fileNames.at(i));
        if(item.type != SLEPItem::NONE){
            itemModel->insertRow(0);
            slepItemList->insert(0,item);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileNames.at(i)).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),item.info());
            itemModel->setData(itemModel->index(0,3),fileNames.at(i));
        }
    }
}



void SLEPFileTable::actAddVector(){
    int i;
    SLEPItem item;
    QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open vector"), tr("."), tr("All Formats (*.vec *.vct *.vctr *.vecb *.vcb *.vctb);;"
                                                                                                    "Vector (*.vec *.vct *.vctr);;"
                                                                                              "Vector (binary storage) (*.vecb *.vcb *.vctb);;"
                                                                                              "All Files(*.*)"));

    for(i=0; i<fileNames.size(); i++){
        if( (QFileInfo(fileNames.at(i)).suffix().compare("vctb",Qt::CaseInsensitive)==0)
                    ||	(QFileInfo(fileNames.at(i)).suffix().compare("vcb",Qt::CaseInsensitive)==0)
                    ||	(QFileInfo(fileNames.at(i)).suffix().compare("vecb",Qt::CaseInsensitive)==0))
            item = SLEPFileOperations::readFile(fileNames.at(i));
        else
            item = SLEPFileOperations::readTextFile(fileNames.at(i));
        if(item.type != SLEPItem::NONE){
            itemModel->insertRow(0);
            slepItemList->insert(0,item);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileNames.at(i)).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),item.info());
            itemModel->setData(itemModel->index(0,3),fileNames.at(i));
        }
    }
}


void SLEPFileTable::actAddGroupIndices(){
    int i;
    SLEPItem item;
    QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open group information file"), tr("."), tr("Group indices (*.grp);;"));

    for(i=0; i<fileNames.size(); i++){
        if( (QFileInfo(fileNames.at(i)).suffix().compare("grp",Qt::CaseInsensitive)==0))
            item = SLEPFileOperations::readTextFile(fileNames.at(i));
        if(item.type != SLEPItem::NONE){
            itemModel->insertRow(0);
            slepItemList->insert(0,item);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileNames.at(i)).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),item.info());
            itemModel->setData(itemModel->index(0,3),fileNames.at(i));
        }
    }
}

void SLEPFileTable::actRemove(){
    int i;

    if(selection->hasSelection()){
        for(i=0; i< itemModel->rowCount(); ++i)
            if(selection->isRowSelected(i,treeView->rootIndex())){
                itemModel->removeRow(i);
                SLEPItem item = slepItemList->at(i);
                item.dealloc();
                slepItemList->removeAt(i);
            }
    }
}



void SLEPFileTable::actAddRandomData(){
    SLEPItem *item = new SLEPItem;
    QString saveFileAs;
    SLEPRandomDataWizard *randomDataWizard = new SLEPRandomDataWizard(*item, this);
    randomDataWizard->exec();
    if(item->type == SLEPItem::NONE)
        return;
    if(item->type== SLEPItem::DENSE_MATRIX || item->type== SLEPItem::SPARSE_MATRIX_CSC){
        saveFileAs = QFileDialog::getSaveFileName(this, tr("Save random matrix"), tr("."), tr("*.mtx"));
        SLEPFileOperations::writeFile(*item, saveFileAs);
    }else if(item->type== SLEPItem::DENSE_VECTOR || item->type== SLEPItem::SPARSE_VECTOR){
        saveFileAs = QFileDialog::getSaveFileName(this, tr("Save random vector"), tr("."), tr("*.vcb"));
        SLEPFileOperations::writeFile(*item, saveFileAs);
	}else if(item->type== SLEPItem::GROUP_INDICES){
        saveFileAs = QFileDialog::getSaveFileName(this, tr("Save random group information"), tr("."), tr("*.grp"));
        SLEPFileOperations::writeTextFile(*item, saveFileAs);
	}

    QFileInfo fileInfo(saveFileAs);

    itemModel->insertRow(0);
    slepItemList->insert(0,*item);
    itemModel->setData(itemModel->index(0,0),fileInfo.baseName());
    itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
    itemModel->setData(itemModel->index(0,2),item->info());
    itemModel->setData(itemModel->index(0,3),saveFileAs);

}


void SLEPFileTable::actView(){
    int i;

    if(selection->hasSelection()){
        for(i=0; i< itemModel->rowCount(); ++i)
            if(selection->isRowSelected(i,treeView->rootIndex())){
                QString var = (itemModel->data(itemModel->index(i,0))).toString();
                selection->currentIndex().row();
                SLEPItem item = slepItemList->at(i);
                if(item.type == SLEPItem::DENSE_MATRIX)
                    twoDViewer(item.data,item.m,item.n,var);
                else if(item.type == SLEPItem::DENSE_VECTOR)
                    oneDViewer(item.data,item.dimension,var);
                else return;
            }
    }
}



int SLEPFileTable::getSelection(){
    int i;
    if(selection->hasSelection()){
        for(i=0; i< itemModel->rowCount(); ++i)
            if(selection->isRowSelected(i,treeView->rootIndex()))
                return i;
    }
    return -1;
}


    int SLEPFileTable::getSelectionType(int selection){
        return (slepItemList->at(selection)).type;
    }

    void SLEPFileTable::getDenseMatrix(int selection, int *m, int *n, double **data){
        *data = (slepItemList->at(selection)).data;
        *m = (slepItemList->at(selection)).m;
        *n = (slepItemList->at(selection)).n;
    }

    void SLEPFileTable::getDenseVector(int selection, int *dimension, double **data){
    *data = (slepItemList->at(selection)).data;
    *dimension = (slepItemList->at(selection)).dimension;
}

    void SLEPFileTable::getGroupIndices(int selection, int *size,int **indices){
		*indices = (slepItemList->at(selection)).group_index;
		*size = (slepItemList->at(selection)).group_size;
}


